-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Post Settings: Refactor revisions handling to avoid performance issues #3233
Conversation
lib/client-assets.php
Outdated
@@ -462,12 +462,12 @@ function gutenberg_extend_wp_api_backbone_client() { | |||
return model.prototype.route && route === model.prototype.route.index; | |||
} ); | |||
}; | |||
wp.api.getPostTypeRevisionsCollection = function( postType ) { | |||
/*wp.api.getPostTypeRevisionsCollection = function( postType ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We no longer need this handler, should we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's dead code, I'm in favor of removing it.
@@ -703,10 +703,6 @@ function gutenberg_editor_scripts_and_styles( $hook ) { | |||
gutenberg_get_rest_link( $post_to_edit, 'about', 'edit' ), | |||
); | |||
|
|||
if ( ! $is_new_post ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my description:
This code preloads API response for revisions endpoint, which fetches all existing post revisions and exposes them in the <script /> tag. When you have let's say 50 revisions, all of them are loaded from the database and exposed in the HTML code leading to the big size of the HTML and increases processing time to process all objects.
And more technical comment from @pento:
Loading all the revisions was running pretty much all of the code that would be run if the posts were being loaded to display on the front end. ‘the_content’ was the biggest problem, but everything added up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, definitely overlooked this 👍
lib/register.php
Outdated
) | ||
); | ||
} | ||
add_action( 'rest_api_init', 'gutenberg_register_post_revisions' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering if it's a good idea to add extra fields to this endpoint. This won't be specific to Gutenberg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm learning WP hooks and APIs. I'm open to suggestions how to implement it better. This change makes loading Gutenberg with tons of revisions comparable to the Classic editor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think a separate endpoint is better, do you know why the previously used endpoint was slow? Maybe we should create a custom endpoint? Also, I'm not 100% confident when it comes to the REST API, others might have a better input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@youknowriad: Loading all the revisions was running pretty much all of the code that would be run if the posts were being loaded to display on the front end. the_content
was the biggest problem, but everything added up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with the field being here for now. I was unfortunately waylaid for the past week or so, so I haven't managed to focus on the REST API problem, but I'm hoping to get back to it later this week. I imagine there'll be a lot of re-shuffling, so I wouldn't get too hung up on where this is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm aware of that, I'm just saying we may want to load the "last_revision_id" and "revision_count" in a separate endpoint instead of adding these as extra fields to the default POST endpoint. Because this change will change the result for everything and not only Gutenberg.
lib/register.php
Outdated
); | ||
} | ||
|
||
function gutenberg_register_post_revisions() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs are missing. I will add later.
While it doesn't appear that it will prevent content filtering from being run, an alternative solution to limiting the size of the version history payload in the upcoming 4.9 release is to specify only the necessary fields on the API request: e.g. |
It seems like this solution makes sense as a temporary workaround. I will clean up this branch and add proper documentation to the
@aduth: Yes, that would be one of the possible ways of improving performance here. I think it would still need more work to make sure that REST API call is triggered every time new post's content is saved. At the moment information about revisions doesn't get updated whenever a post is saved. This PR addresses it, too.
@youknowriad: it is another solution that would work. Again, we would need to find a way to refresh data each time post is saved. @pento post data structure contains a list of categories or tags, why this is not the case for revisions? I'm sure there are reasons like we don't want to fetch everything and ruin performance. According to the documentation, we can pass |
2086951
to
69fbe32
Compare
Codecov Report
@@ Coverage Diff @@
## master #3233 +/- ##
=========================================
+ Coverage 31.16% 31.2% +0.04%
=========================================
Files 229 229
Lines 6431 6428 -3
Branches 1145 1145
=========================================
+ Hits 2004 2006 +2
+ Misses 3716 3711 -5
Partials 711 711
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get this in (for the release) and make sure we revisit the endpoint later
Thanks for all your feedback and reviews 🙇 I'll open a follow-up issue. Let's discuss further steps there. |
Description
Fixes #3167 - Post edit script takes way much longer to generate for Gutenberg editor. With the help of @pento we were able to identify the root cause:
This code preloads API response for revisions endpoint, which fetches all existing post revisions and exposes them in the
<script />
tag. When you have let's say 50 revisions, all of them are loaded from the database and exposed in the HTML code leading to the big size of the HTML and processing time to create all objects.I refactored the handling of revisions to extend REST API endpoint for post types to include information about the number of revisions and the last revision id.
It solves a few issues I noticed:
How Has This Been Tested?
Manually:
Screenshots (jpeg or gifs if applicable):
Types of changes
Bug fix (non-breaking change which fixes an issue). Code was refactored.
Checklist: